import fs from 'fs';
import path from 'path';

// JSON数据库文件路径
const dataDir = path.join(process.cwd(), 'data');
const classificationsPath = path.join(dataDir, 'classifications.json');
const attributesPath = path.join(dataDir, 'attributes.json');
const entitiesPath = path.join(dataDir, 'entities.json');
const parameterMappingsPath = path.join(dataDir, 'parameter_mappings.json');

// 确保数据目录存在
if (!fs.existsSync(dataDir)) {
  fs.mkdirSync(dataDir, { recursive: true });
}

// 01015分类标准表
export interface ClassificationRecord {
  id?: number;
  code: string;
  name: string;
  level: string;
  parent_code?: string;
  description?: string;
  sheet_name: string;
  created_at?: string;
}

// 属性表（C开头的表）
export interface AttributeRecord {
  id?: number;
  classification_code: string;
  attribute_name: string;
  attribute_type?: string;
  is_required?: boolean;
  default_value?: string;
  description?: string;
  sheet_name: string;
  created_at?: string;
}

// 实体对象表
export interface EntityRecord {
  id?: number;
  name: string;
  code?: string;
  category?: string;
  standard_name?: string;
  standard_code?: string;
  specialty: string; // electrical, hvac, communication, instrumentation
  created_at?: string;
}

// 参数映射表
export interface ParameterMappingRecord {
  id?: number;
  entity_id: number;
  classification_code: string;
  parameter_type: 'naming' | 'location' | 'basic';
  parameter_name: string;
  parameter_value?: string;
  created_at?: string;
}

// JSON文件读写工具函数
function readJsonFile<T>(filePath: string): T[] {
  try {
    if (fs.existsSync(filePath)) {
      const data = fs.readFileSync(filePath, 'utf-8');
      return JSON.parse(data);
    }
    return [];
  } catch (error) {
    console.error(`Error reading file ${filePath}:`, error);
    return [];
  }
}

function writeJsonFile<T>(filePath: string, data: T[]): void {
  try {
    fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');
  } catch (error) {
    console.error(`Error writing file ${filePath}:`, error);
  }
}

// 初始化数据库表
export function initializeDatabase() {
  console.log('Initializing JSON database...');
  
  // 创建空的JSON文件如果不存在
  if (!fs.existsSync(classificationsPath)) {
    writeJsonFile(classificationsPath, []);
  }
  if (!fs.existsSync(attributesPath)) {
    writeJsonFile(attributesPath, []);
  }
  if (!fs.existsSync(entitiesPath)) {
    writeJsonFile(entitiesPath, []);
  }
  if (!fs.existsSync(parameterMappingsPath)) {
    writeJsonFile(parameterMappingsPath, []);
  }
  
  console.log('JSON database initialized successfully');
}

// 分类标准数据操作
export class ClassificationDAO {
  private getNextId(data: ClassificationRecord[]): number {
    return data.length > 0 ? Math.max(...data.map(item => item.id || 0)) + 1 : 1;
  }

  insert(record: ClassificationRecord): void {
    const data = readJsonFile<ClassificationRecord>(classificationsPath);
    const existingIndex = data.findIndex(item => item.code === record.code);
    
    if (existingIndex >= 0) {
      // Update existing record
      data[existingIndex] = { ...record, id: data[existingIndex].id };
    } else {
      // Insert new record
      record.id = this.getNextId(data);
      record.created_at = new Date().toISOString();
      data.push(record);
    }
    
    writeJsonFile(classificationsPath, data);
  }

  findByCode(code: string): ClassificationRecord | null {
    const data = readJsonFile<ClassificationRecord>(classificationsPath);
    return data.find(item => item.code === code) || null;
  }

  findBySheet(sheetName: string): ClassificationRecord[] {
    const data = readJsonFile<ClassificationRecord>(classificationsPath);
    return data.filter(item => item.sheet_name === sheetName);
  }

  findAll(): ClassificationRecord[] {
    const data = readJsonFile<ClassificationRecord>(classificationsPath);
    return data.sort((a, b) => a.code.localeCompare(b.code));
  }

  insertMany(records: ClassificationRecord[]): void {
    for (const record of records) {
      this.insert(record);
    }
  }
}

// 属性数据操作
export class AttributeDAO {
  private getNextId(data: AttributeRecord[]): number {
    return data.length > 0 ? Math.max(...data.map(item => item.id || 0)) + 1 : 1;
  }

  insert(record: AttributeRecord): void {
    const data = readJsonFile<AttributeRecord>(attributesPath);
    const existingIndex = data.findIndex(item => 
      item.classification_code === record.classification_code && 
      item.attribute_name === record.attribute_name
    );
    
    if (existingIndex >= 0) {
      // Update existing record
      data[existingIndex] = { ...record, id: data[existingIndex].id };
    } else {
      // Insert new record
      record.id = this.getNextId(data);
      record.created_at = new Date().toISOString();
      data.push(record);
    }
    
    writeJsonFile(attributesPath, data);
  }

  findByClassification(classificationCode: string): AttributeRecord[] {
    const data = readJsonFile<AttributeRecord>(attributesPath);
    return data.filter(item => item.classification_code === classificationCode);
  }

  findBySheet(sheetName: string): AttributeRecord[] {
    const data = readJsonFile<AttributeRecord>(attributesPath);
    return data.filter(item => item.sheet_name === sheetName);
  }

  insertMany(records: AttributeRecord[]): void {
    for (const record of records) {
      this.insert(record);
    }
  }
}

// 实体对象数据操作
export class EntityDAO {
  private getNextId(data: EntityRecord[]): number {
    return data.length > 0 ? Math.max(...data.map(item => item.id || 0)) + 1 : 1;
  }

  insert(record: EntityRecord): number {
    const data = readJsonFile<EntityRecord>(entitiesPath);
    const existingIndex = data.findIndex(item => 
      item.name === record.name && item.specialty === record.specialty
    );
    
    if (existingIndex >= 0) {
      // Update existing record
      data[existingIndex] = { ...record, id: data[existingIndex].id };
      writeJsonFile(entitiesPath, data);
      return data[existingIndex].id!;
    } else {
      // Insert new record
      record.id = this.getNextId(data);
      record.created_at = new Date().toISOString();
      data.push(record);
      writeJsonFile(entitiesPath, data);
      return record.id;
    }
  }

  findBySpecialty(specialty: string): EntityRecord[] {
    const data = readJsonFile<EntityRecord>(entitiesPath);
    return data.filter(item => item.specialty === specialty);
  }

  findById(id: number): EntityRecord | null {
    const data = readJsonFile<EntityRecord>(entitiesPath);
    return data.find(item => item.id === id) || null;
  }

  insertMany(records: EntityRecord[]): void {
    for (const record of records) {
      this.insert(record);
    }
  }
}

// 参数映射数据操作
export class ParameterMappingDAO {
  private getNextId(data: ParameterMappingRecord[]): number {
    return data.length > 0 ? Math.max(...data.map(item => item.id || 0)) + 1 : 1;
  }

  insert(record: ParameterMappingRecord): void {
    const data = readJsonFile<ParameterMappingRecord>(parameterMappingsPath);
    record.id = this.getNextId(data);
    record.created_at = new Date().toISOString();
    data.push(record);
    writeJsonFile(parameterMappingsPath, data);
  }

  findByEntityAndType(entityId: number, parameterType: 'naming' | 'location' | 'basic'): any[] {
    const data = readJsonFile<ParameterMappingRecord>(parameterMappingsPath);
    const classifications = readJsonFile<ClassificationRecord>(classificationsPath);
    const attributes = readJsonFile<AttributeRecord>(attributesPath);
    
    const mappings = data.filter(item => 
      item.entity_id === entityId && item.parameter_type === parameterType
    );
    
    // Join with classifications and attributes
    return mappings.map(mapping => {
      const classification = classifications.find(c => c.code === mapping.classification_code);
      const attribute = attributes.find(a => 
        a.classification_code === mapping.classification_code && 
        a.attribute_name === mapping.parameter_name
      );
      
      return {
        ...mapping,
        classification_name: classification?.name || '',
        attribute_type: attribute?.attribute_type || 'string',
        is_required: attribute?.is_required || false,
        default_value: attribute?.default_value || ''
      };
    }).sort((a, b) => a.parameter_name.localeCompare(b.parameter_name));
  }

  findBySpecialtyAndType(specialty: string, parameterType: 'naming' | 'location' | 'basic'): any[] {
    const data = readJsonFile<ParameterMappingRecord>(parameterMappingsPath);
    const entities = readJsonFile<EntityRecord>(entitiesPath);
    const classifications = readJsonFile<ClassificationRecord>(classificationsPath);
    
    const specialtyEntities = entities.filter(e => e.specialty === specialty);
    const entityIds = specialtyEntities.map(e => e.id!);
    
    const mappings = data.filter(item => 
      entityIds.includes(item.entity_id) && item.parameter_type === parameterType
    );
    
    // Join with entities and classifications
    return mappings.map(mapping => {
      const entity = specialtyEntities.find(e => e.id === mapping.entity_id);
      const classification = classifications.find(c => c.code === mapping.classification_code);
      
      return {
        ...mapping,
        entity_name: entity?.name || '',
        specialty: entity?.specialty || '',
        classification_name: classification?.name || ''
      };
    }).sort((a, b) => {
      if (a.entity_name !== b.entity_name) {
        return a.entity_name.localeCompare(b.entity_name);
      }
      return a.parameter_name.localeCompare(b.parameter_name);
    });
  }

  insertMany(records: ParameterMappingRecord[]): void {
    for (const record of records) {
      this.insert(record);
    }
  }
}

// 导出DAO实例
export const classificationDAO = new ClassificationDAO();
export const attributeDAO = new AttributeDAO();
export const entityDAO = new EntityDAO();
export const parameterMappingDAO = new ParameterMappingDAO(); 